unit uDirect3D8;

{$MINENUMSIZE 4}
{$ALIGN ON}

interface

uses
	Windows;

const
  Direct3D8Lib = 'd3d8.dll';
  
  D3DCLEAR_TARGET = $00000001;

  D3DBLEND_SRCALPHA    = 5;
  D3DBLEND_INVSRCALPHA = 6;

  D3DTADDRESS_BORDER = 4;

  D3DPT_POINTLIST     = 1;
  D3DPT_LINELIST      = 2;
  D3DPT_LINESTRIP     = 3;
  D3DPT_TRIANGLELIST  = 4;
  D3DPT_TRIANGLESTRIP = 5;
  D3DPT_TRIANGLEFAN   = 6;

  D3DTS_VIEW       = 2;
  D3DTS_PROJECTION = 3;
  D3DTS_WORLD      = 256;

  D3DRS_ALPHATESTENABLE  = 15;
  D3DRS_SRCBLEND         = 19;
  D3DRS_DESTBLEND        = 20;
  D3DRS_ALPHABLENDENABLE = 27;
  D3DRS_LIGHTING         = 137;

  D3DTSS_COLOROP     = 1;
  D3DTSS_COLORARG1   = 2;
  D3DTSS_COLORARG2   = 3;
  D3DTSS_ALPHAOP     = 4;
  D3DTSS_ALPHAARG1   = 5;
  D3DTSS_ALPHAARG2   = 6;
  D3DTSS_ADDRESSU    = 13;
  D3DTSS_ADDRESSV    = 14;
  D3DTSS_BORDERCOLOR = 15;
  D3DTSS_MAGFILTER   = 16;
  D3DTSS_MINFILTER   = 17;
  D3DTSS_COLORARG0   = 26;
  D3DTSS_ALPHAARG0   = 27;

  D3DTOP_MODULATE = 4;

  D3DTA_DIFFUSE = $00000000;
  D3DTA_TEXTURE = $00000002;

  D3DTEXF_POINT       = 1;
  D3DTEXF_LINEAR      = 2;
  D3DTEXF_ANISOTROPIC = 3;

  D3DFVF_XYZ     = $002;
  D3DFVF_DIFFUSE = $040;
  D3DFVF_TEX1    = $100;

  D3DDEVTYPE_HAL = 1;
  D3DDEVTYPE_REF = 2;
  D3DDEVTYPE_SW  = 3;

  D3DFMT_UNKNOWN  =  0;
  D3DFMT_R8G8B8   = 20;
  D3DFMT_A8R8G8B8 = 21;
  D3DFMT_X8R8G8B8 = 22;
  D3DFMT_A4R4G4B4 = 26;
  D3DFMT_A8       = 28;

  D3DSWAPEFFECT_DISCARD = 1;

  D3DPOOL_DEFAULT = 0;
  D3DPOOL_MANAGED = 1;

  D3DLOCK_READONLY = $00000010;
  D3DLOCK_DISCARD  = $00002000;

  D3DPRESENT_INTERVAL_ONE        = $00000001;
  D3DPRESENT_INTERVAL_IMMEDIATE  = $80000000;
  D3DDEVCAPS_HWTRANSFORMANDLIGHT = $00010000;

  D3D_SDK_VERSION = DWord(220);

  D3DCREATE_SOFTWARE_VERTEXPROCESSING     = $00000020;
  D3DCREATE_HARDWARE_VERTEXPROCESSING     = $00000040;

  MAKE_D3DHRESULT_R = (1 shl 31) or ($876 shl 16);

  D3D_OK = S_OK;

  D3DERR_DEVICENOTRESET = HResult(MAKE_D3DHRESULT_R or 2153);

type
  TD3DValue = Single;
  PD3DValue = ^TD3DValue;

  TD3DColor = DWord;
  PD3DColor = ^TD3DColor;

  PD3DVector = ^TD3DVector;
  TD3DVector = packed record
    x: Single;
    y: Single;
    z: Single;
  end;

type
  PD3DMatrix = ^TD3DMatrix;
  TD3DMatrix = packed record
    case integer of
      0 : (_11, _12, _13, _14: Single;
           _21, _22, _23, _24: Single;
           _31, _32, _33, _34: Single;
           _41, _42, _43, _44: Single);
      1 : (m : array [0..3, 0..3] of Single);
  end;

  PD3DDisplayMode = ^TD3DDisplayMode;
  TD3DDisplayMode = packed record
    Width: LongWord;
    Height: LongWord;
    RefreshRate: LongWord;
    Format: DWord;
  end;

  PD3DPresentParameters = ^TD3DPresentParameters;
  TD3DPresentParameters = packed record
    BackBufferWidth:                    LongWord;
    BackBufferHeight:                   LongWord;
    BackBufferFormat:                   DWord;
    BackBufferCount:                    LongWord;

    MultiSampleType:                    DWord;

    SwapEffect:                         DWord;
    hDeviceWindow:                      HWND;
    Windowed:                           Bool;
    EnableAutoDepthStencil:             Bool;
    AutoDepthStencilFormat:             DWord;
    Flags: LongInt;

    FullScreen_RefreshRateInHz:         LongWord;
    FullScreen_PresentationInterval:    LongWord;
  end;

  PD3DLockedRect = ^TD3DLockedRect;
  TD3DLockedRect = packed record
    Pitch: Integer;
    pBits: Pointer;
  end;

  PD3DCaps8 = ^TD3DCaps8;
  TD3DCaps8 = record
    DeviceType: DWord;
    AdapterOrdinal: DWord;

    Caps: DWord;
    Caps2: DWord;
    Caps3: DWord;
    PresentationIntervals: DWord;

    CursorCaps: DWORD;

    DevCaps: DWord;
    PrimitiveMiscCaps: DWord;
    RasterCaps: DWord;
    ZCmpCaps: DWord;
    SrcBlendCaps: DWord;
    DestBlendCaps: DWord;
    AlphaCmpCaps: DWord;
    ShadeCaps: DWord;
    TextureCaps: DWord;
    TextureFilterCaps: DWord;
    CubeTextureFilterCaps: DWord;
    VolumeTextureFilterCaps: DWord;
    TextureAddressCaps: DWord;
    VolumeTextureAddressCaps: DWord;

    LineCaps: DWord;

    MaxTextureWidth, MaxTextureHeight: DWord;
    MaxVolumeExtent: DWord;

    MaxTextureRepeat: DWord;
    MaxTextureAspectRatio: DWord;
    MaxAnisotropy: DWord;
    MaxVertexW: Single;

    GuardBandLeft: Single;
    GuardBandTop: Single;
    GuardBandRight: Single;
    GuardBandBottom: Single;

    ExtentsAdjust: Single;
    StencilCaps: DWord;

    FVFCaps: DWord;
    TextureOpCaps: DWord;
    MaxTextureBlendStages: DWord;
    MaxSimultaneousTextures: DWord;

    VertexProcessingCaps: DWord;
    MaxActiveLights: DWord;
    MaxUserClipPlanes: DWord;
    MaxVertexBlendMatrices: DWord;
    MaxVertexBlendMatrixIndex: DWord;

    MaxPointSize: Single;

    MaxPrimitiveCount: DWord;
    MaxVertexIndex: DWord;
    MaxStreams: DWord;
    MaxStreamStride: DWord;

    VertexShaderVersion: DWord;
    MaxVertexShaderConst: DWord;

    PixelShaderVersion: DWord;
    MaxPixelShaderValue: Single;
  end;
  
  IDirect3D8 = interface;
  IDirect3DDevice8 = interface;
  IDirect3DResource8 = interface;
  IDirect3DBaseTexture8 = interface;
  IDirect3DTexture8 = interface;

  IDirect3D8 = interface(IUnknown)
    ['{1DD9E8DA-1C77-4d40-B0CF-98FEFDFF9512}']
    function RegisterSoftwareDevice(pInitializeFunction: Pointer): HResult; stdcall;
    function GetAdapterCount: LongWord; stdcall;
    function GetAdapterIdentifier(Adapter: LongWord; Flags: DWord; out pIdentifier): HResult; stdcall;
    function GetAdapterModeCount (Adapter: LongWord): LongWord; stdcall;
    function EnumAdapterModes(Adapter, Mode: LongWord; out pMode: TD3DDisplayMode): HResult; stdcall;
    function GetAdapterDisplayMode(Adapter: LongWord; out pMode: TD3DDisplayMode): HResult; stdcall;
    function CheckDeviceType(Adapter: LongWord; CheckType: DWord; DisplayFormat, BackBufferFormat: DWord; Windowed: BOOL): HResult; stdcall;
    function CheckDeviceFormat(Adapter: LongWord; DeviceType: DWord; AdapterFormat: DWord; Usage: DWord; RType: DWord; CheckFormat: DWord): HResult; stdcall;
    function CheckDeviceMultiSampleType(Adapter: LongWord; DeviceType: DWord; SurfaceFormat: DWord; Windowed: BOOL; MultiSampleType: DWord): HResult; stdcall;
    function CheckDepthStencilMatch(Adapter: LongWord; DeviceType: DWord; AdapterFormat, RenderTargetFormat, DepthStencilFormat: DWord): HResult; stdcall;
    function GetDeviceCaps(Adapter: LongWord; DeviceType: DWord; out pCaps: TD3DCaps8): HResult; stdcall;
    function GetAdapterMonitor(Adapter: LongWord): THandle; stdcall;
    function CreateDevice(Adapter: LongWord; DeviceType: DWord; hFocusWindow: HWND; BehaviorFlags: DWord; var pPresentationParameters: TD3DPresentParameters; out ppReturnedDeviceInterface: IDirect3DDevice8): HResult; stdcall;
  end;
  
  IDirect3DDevice8 = interface(IUnknown)
    ['{7385E5DF-8FE8-41D5-86B6-D7B48547B6CF}']
    function TestCooperativeLevel: HResult; stdcall;
    function GetAvailableTextureMem: LongWord; stdcall;
    function ResourceManagerDiscardBytes(Bytes: DWord): HResult; stdcall;
    function GetDirect3D(out ppD3D8: IDirect3D8): HResult; stdcall;
    function GetDeviceCaps(out pCaps: TD3DCaps8): HResult; stdcall;
    function GetDisplayMode(out pMode: TD3DDisplayMode): HResult; stdcall;
    function GetCreationParameters(out pParameters): HResult; stdcall;
    function SetCursorProperties(XHotSpot, YHotSpot: LongWord; pCursorBitmap: Pointer): HResult; stdcall;
    procedure SetCursorPosition(XScreenSpace, YScreenSpace: Integer; Flags: DWord); stdcall;
    function ShowCursor(bShow: BOOL): BOOL; stdcall;
    function CreateAdditionalSwapChain(const pPresentationParameters: TD3DPresentParameters; out pSwapChain: Pointer): HResult; stdcall;
    function Reset(const pPresentationParameters: TD3DPresentParameters): HResult; stdcall;
    function Present(pSourceRect, pDestRect: PRect; hDestWindowOverride: HWND; pDirtyRegion: PRgnData): HResult; stdcall;
    function GetBackBuffer(BackBuffer: LongWord; _Type: DWord; out ppBackBuffer): HResult; stdcall;
    function GetRasterStatus(out pRasterStatus): HResult; stdcall;
    procedure SetGammaRamp(Flags: DWord; const pRamp); stdcall;
    procedure GetGammaRamp(out pRamp); stdcall;
    function CreateTexture(Width, Height, Levels: LongWord; Usage: DWord; Format: DWord; Pool: DWord; out ppTexture: IDirect3DTexture8): HResult; stdcall;
    function CreateVolumeTexture(Width, Height, Depth, Levels: LongWord; Usage: DWord; Format: DWord; Pool: DWord; out ppVolumeTexture: Pointer): HResult; stdcall;
    function CreateCubeTexture(EdgeLength, Levels: LongWord; Usage: DWord; Format: DWord; Pool: DWord; out ppCubeTexture: Pointer): HResult; stdcall;
    function CreateVertexBuffer(Length: LongWord; Usage, FVF: DWord; Pool: DWord; out ppVertexBuffer: Pointer): HResult; stdcall;
    function CreateIndexBuffer(Length: LongWord; Usage: DWord; Format: DWord; Pool: DWord; out ppIndexBuffer: Pointer): HResult; stdcall;
    function CreateRenderTarget(Width, Height: LongWord; Format: DWord; MultiSample: DWord; Lockable: BOOL; out ppSurface: Pointer): HResult; stdcall;
    function CreateDepthStencilSurface(Width, Height: LongWord; Format: DWord; MultiSample: DWord; out ppSurface: Pointer): HResult; stdcall;
    function CreateImageSurface(Width, Height: LongWord; Format: DWord; out ppSurface: Pointer): HResult; stdcall;
    function CopyRects(pSourceSurface: Pointer; pSourceRectsArray: PRect; cRects: LongWord; out pDestinationSurface: Pointer; pDestPointsArray: PPoint): HResult; stdcall;
    function UpdateTexture(pSourceTexture, pDestinationTexture: IDirect3DBaseTexture8): HResult; stdcall;
    function GetFrontBuffer(pDestSurface: Pointer): HResult; stdcall;
    function SetRenderTarget(pRenderTarget, pNewZStencil: Pointer): HResult; stdcall;
    function GetRenderTarget(out ppRenderTarget: Pointer): HResult; stdcall;
    function GetDepthStencilSurface(out ppZStencilSurface: Pointer): HResult; stdcall;
    function BeginScene: HResult; stdcall;
    function EndScene: HResult; stdcall;
    function Clear(Count: DWord; pRects: Pointer; Flags: DWord; Color: TD3DColor; Z: Single; Stencil: DWord): HResult; stdcall;
    function SetTransform(State: DWord; const pMatrix: TD3DMatrix): HResult; stdcall;
    function GetTransform(State: DWord; out pMatrix: TD3DMatrix): HResult; stdcall;
    function MultiplyTransform(State: DWord; const pMatrix: TD3DMatrix): HResult; stdcall;
    function SetViewport(const pViewport): HResult; stdcall;
    function GetViewport(out pViewport): HResult; stdcall;
    function SetMaterial(const pMaterial): HResult; stdcall;
    function GetMaterial(out pMaterial): HResult; stdcall;
    function SetLight(Index: DWord; const pLight): HResult; stdcall;
    function GetLight(Index: DWord; out pLights): HResult; stdcall;
    function LightEnable(Index: DWord; Enable: BOOL): HResult; stdcall;
    function GetLightEnable(Index: DWord; out pEnable: BOOL): HResult; stdcall;
    function SetClipPlane(Index: DWord; pPlane: PSingle): HResult; stdcall;
    function GetClipPlane(Index: DWord; pPlane: PSingle): HResult; stdcall;
    function SetRenderState(State: DWord; Value: DWord): HResult; stdcall;
    function GetRenderState(State: DWord; out pValue: DWord): HResult; stdcall;
    function BeginStateBlock: HResult; stdcall;
    function EndStateBlock(out pToken: DWord): HResult; stdcall;
    function ApplyStateBlock(Token: DWord): HResult; stdcall;
    function CaptureStateBlock(Token: DWord): HResult; stdcall;
    function DeleteStateBlock(Token: DWord): HResult; stdcall;
    function CreateStateBlock(_Type: Dword; out Token: DWord): HResult; stdcall;
    function SetClipStatus(const pClipStatus): HResult; stdcall;
    function GetClipStatus(out pClipStatus): HResult; stdcall;
    function GetTexture(Stage: DWord; out ppTexture: IDirect3DBaseTexture8): HResult; stdcall;
    function SetTexture(Stage: DWord; pTexture: IDirect3DBaseTexture8): HResult; stdcall;
    function GetTextureStageState(Stage: DWord; _Type: DWord; out pValue: DWord): HResult; stdcall;
    function SetTextureStageState(Stage: DWord; _Type: DWord; Value: DWord): HResult; stdcall;
    function ValidateDevice(out pNumPasses: DWord): HResult; stdcall;
    function GetInfo(DevInfoID: DWord; out pDevInfoStruct; DevInfoStructSize: DWord): HResult; stdcall;
    function SetPaletteEntries(PaletteNumber: LongWord; pEntries: pPaletteEntry): HResult; stdcall;
    function GetPaletteEntries(PaletteNumber: LongWord; pEntries: pPaletteEntry): HResult; stdcall;
    function SetCurrentTexturePalette(PaletteNumber: LongWord): HResult; stdcall;
    function GetCurrentTexturePalette(out PaletteNumber: LongWord): HResult; stdcall;
    function DrawPrimitive(PrimitiveType: DWord; StartVertex, PrimitiveCount: LongWord): HResult; stdcall;
    function DrawIndexedPrimitive(_Type: DWord; minIndex, NumVertices, startIndex, primCount: LongWord): HResult; stdcall;
    function DrawPrimitiveUP(PrimitiveType: DWord; PrimitiveCount: LongWord; const pVertexStreamZeroData; VertexStreamZeroStride: LongWord): HResult; stdcall;
    function DrawIndexedPrimitiveUP(PrimitiveType: DWord; MinVertexIndex, NumVertexIndices, PrimitiveCount: LongWord; const pIndexData; IndexDataFormat: DWord; const pVertexStreamZeroData; VertexStreamZeroStride: LongWord): HResult; stdcall;
    function ProcessVertices(SrcStartIndex, DestIndex, VertexCount: LongWord; pDestBuffer: Pointer; Flags: DWord): HResult; stdcall;
    function CreateVertexShader(pDeclaration, pFunction: PDWord; out pHandle: DWord; Usage: DWord): HResult; stdcall;
    function SetVertexShader(Handle: DWord): HResult; stdcall;
    function GetVertexShader(out pHandle: DWord): HResult; stdcall;
    function DeleteVertexShader(Handle: DWord): HResult; stdcall;
    function SetVertexShaderConstant(_Register: DWord; const pConstantData; ConstantCount: DWord): HResult; stdcall;
    function GetVertexShaderConstant(_Register: DWord; out pConstantData; ConstantCount: DWord): HResult; stdcall;
    function GetVertexShaderDeclaration(Handle: DWord; pData: Pointer; out pSizeOfData: DWord): HResult; stdcall;
    function GetVertexShaderFunction(Handle: DWord; pData: Pointer; out pSizeOfData: DWord): HResult; stdcall;
    function SetStreamSource(StreamNumber: LongWord; pStreamData: Pointer; Stride: LongWord): HResult; stdcall;
    function GetStreamSource(StreamNumber: LongWord; out ppStreamData: Pointer; out pStride: LongWord): HResult; stdcall;
    function SetIndices(pIndexData: Pointer; BaseVertexIndex: LongWord): HResult; stdcall;
    function GetIndices(out ppIndexData: Pointer; out pBaseVertexIndex: LongWord): HResult; stdcall;
    function CreatePixelShader(pFunction: PDWord; out pHandle: DWord): HResult; stdcall;
    function SetPixelShader(Handle: DWord): HResult; stdcall;
    function GetPixelShader(out Handle: DWord): HResult; stdcall;
    function DeletePixelShader(Handle: DWord): HResult; stdcall;
    function SetPixelShaderConstant(_Register: DWord; const pConstantData; ConstantCount: DWord): HResult; stdcall;
    function GetPixelShaderConstant(_Register: DWord; out pConstantData; ConstantCount: DWord): HResult; stdcall;
    function GetPixelShaderFunction(Handle: DWord; pData: Pointer; var pSizeOfData: DWord): HResult; stdcall;
    function DrawRectPatch(Handle: LongWord; pNumSegs: PSingle; pTriPatchInfo: Pointer): HResult; stdcall;
    function DrawTriPatch(Handle: LongWord; pNumSegs: PSingle; pTriPatchInfo: Pointer): HResult; stdcall;
    function DeletePatch(Handle: LongWord): HResult; stdcall;
  end;

  IDirect3DResource8 = interface(IUnknown)
    ['{1B36BB7B-09B7-410a-B445-7D1430D7B33F}']
    function GetDevice(out ppDevice: IDirect3DDevice8): HResult; stdcall;
    function SetPrivateData(const refguid: TGUID; const pData; SizeOfData, Flags: DWord): HResult; stdcall;
    function GetPrivateData(const refguid: TGUID; pData: Pointer; out pSizeOfData: DWord): HResult; stdcall;
    function FreePrivateData(const refguid: TGUID): HResult; stdcall;
    function SetPriority(PriorityNew: DWord): DWord; stdcall;
    function GetPriority: DWord; stdcall;
    procedure PreLoad; stdcall;
    function GetType: DWord; stdcall;
  end;

  IDirect3DBaseTexture8 = interface(IDirect3DResource8)
    ['{B4211CFA-51B9-4a9f-AB78-DB99B2BB678E}']
    function SetLOD(LODNew: DWord): DWord; stdcall;
    function GetLOD: DWord; stdcall;
    function GetLevelCount: DWord; stdcall;
  end;

  IDirect3DTexture8 = interface(IDirect3DBaseTexture8)
    ['{E4CDD575-2866-4f01-B12E-7EECE1EC9358}']
    function GetLevelDesc(Level: LongWord; out pDesc): HResult; stdcall;
    function GetSurfaceLevel(Level: LongWord; out ppSurfaceLevel: Pointer): HResult; stdcall;
    function LockRect(Level: LongWord; out pLockedRect: TD3DLockedRect; pRect: PRect; Flags: DWord): HResult; stdcall;
    function UnlockRect(Level: LongWord): HResult; stdcall;
    function AddDirtyRect(pDirtyRect: PRect): HResult; stdcall;
  end;

function Direct3DCreate8(SDKVersion: LongWord): IDirect3D8; stdcall;

function InitDirect3D8(libName: String = Direct3D8Lib): Boolean;

implementation

uses
  uLib;

var
  Direct3DCreate8Lib: function(SDKVersion: LongWord): Pointer; stdcall;

function Direct3DCreate8(SDKVersion: LongWord): IDirect3D8;
begin
  Result:= IDirect3D8(Direct3DCreate8Lib(SDKVersion));

  if Assigned(Result) then
    Result._Release;
end;

function InitDirect3D8(libName: String = Direct3D8Lib): Boolean;
var
  lib: Cardinal;
begin
  Result := False;

  lib := LibOpen(libName);

  if lib <> 0 then
  begin
    Direct3DCreate8Lib := LibProc(lib, 'Direct3DCreate8');

    Result := True;
  end;
end;

end.
